home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
ctags.lha
/
ctags-3.0.3
/
eiffel.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-17
|
25KB
|
1,018 lines
/*****************************************************************************
* $Id: eiffel.c,v 7.5 1998/12/21 05:55:09 darren Exp $
*
* Copyright (c) 1998, Darren Hiebert
*
* This source code is released for free distribution under the terms of the
* GNU General Public License.
*
* This module contains functions for generating tags for Eiffel language
* files.
*****************************************************************************/
/*============================================================================
= Include files
============================================================================*/
#include "general.h"
#include <string.h>
#include <limits.h>
#include <ctype.h> /* to define tolower() */
#include <setjmp.h>
#include "debug.h"
#include "parse.h"
#include "entry.h"
#include "keyword.h"
#include "main.h"
#include "options.h"
#include "read.h"
#include "vstring.h"
/*============================================================================
= Macros
============================================================================*/
#define isFreeOperatorChar(c) ((c) == '@' || (c) == '#' || \
(c) == '|' || (c) == '&')
#define isType(token,t) (boolean)((token)->type == (t))
#define isKeyword(token,k) (boolean)((token)->keyword == (k))
/*============================================================================
= Data declarations
============================================================================*/
typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
/* Used to specify type of keyword.
*/
typedef enum eKeywordId {
KEYWORD_NONE,
KEYWORD_alias, KEYWORD_all, KEYWORD_and, KEYWORD_as, KEYWORD_check,
KEYWORD_class, KEYWORD_creation, KEYWORD_Current, KEYWORD_debug,
KEYWORD_deferred, KEYWORD_do, KEYWORD_else, KEYWORD_elseif, KEYWORD_end,
KEYWORD_ensure, KEYWORD_expanded, KEYWORD_export, KEYWORD_external,
KEYWORD_false, KEYWORD_feature, KEYWORD_from, KEYWORD_frozen, KEYWORD_if,
KEYWORD_implies, KEYWORD_indexing, KEYWORD_infix, KEYWORD_inherit,
KEYWORD_inspect, KEYWORD_invariant, KEYWORD_is, KEYWORD_like,
KEYWORD_local, KEYWORD_loop, KEYWORD_not, KEYWORD_obsolete, KEYWORD_old,
KEYWORD_once, KEYWORD_or, KEYWORD_prefix, KEYWORD_redefine, KEYWORD_rename,
KEYWORD_require, KEYWORD_rescue, KEYWORD_Result, KEYWORD_retry,
KEYWORD_select, KEYWORD_separate, KEYWORD_strip, KEYWORD_then,
KEYWORD_true, KEYWORD_undefine, KEYWORD_unique, KEYWORD_until,
KEYWORD_variant, KEYWORD_when, KEYWORD_xor
} keywordId;
/* Used to determine whether keyword is valid for the token language and
* what its ID is.
*/
typedef struct sKeywordDesc {
const char *name;
keywordId id;
} keywordDesc;
typedef enum eTokenType {
TOKEN_UNDEFINED,
TOKEN_BANG,
TOKEN_CHARACTER,
TOKEN_CLOSE_BRACE,
TOKEN_CLOSE_BRACKET,
TOKEN_CLOSE_PAREN,
TOKEN_COMMA,
TOKEN_COLON,
TOKEN_DOT,
TOKEN_DOLLAR,
TOKEN_IDENTIFIER,
TOKEN_KEYWORD,
TOKEN_NUMERIC,
TOKEN_OPEN_BRACE,
TOKEN_OPEN_BRACKET,
TOKEN_OPEN_PAREN,
TOKEN_OPERATOR,
TOKEN_OTHER,
TOKEN_SEPARATOR,
TOKEN_STRING
} tokenType;
typedef enum eTagType {
TAG_UNDEFINED,
TAG_CLASS,
TAG_FEATURE,
TAG_LOCAL,
TAG_COUNT /* must be last */
} tagType;
typedef struct sTokenInfo {
tokenType type;
keywordId keyword;
boolean isExported;
vString * string;
vString * className;
vString * featureName;
} tokenInfo;
/*============================================================================
= Data definitions
============================================================================*/
static jmp_buf Exception;
static const keywordDesc EiffelKeywordTable[] = {
/* keyword keyword ID */
{ "alias", KEYWORD_alias },
{ "all", KEYWORD_all },
{ "and", KEYWORD_and },
{ "as", KEYWORD_as },
{ "check", KEYWORD_check },
{ "class", KEYWORD_class },
{ "creation", KEYWORD_creation },
{ "current", KEYWORD_Current },
{ "debug", KEYWORD_debug },
{ "deferred", KEYWORD_deferred },
{ "do", KEYWORD_do },
{ "else", KEYWORD_else },
{ "elseif", KEYWORD_elseif },
{ "end", KEYWORD_end },
{ "ensure", KEYWORD_ensure },
{ "expanded", KEYWORD_expanded },
{ "export", KEYWORD_export },
{ "external", KEYWORD_external },
{ "false", KEYWORD_false },
{ "feature", KEYWORD_feature },
{ "from", KEYWORD_from },
{ "frozen", KEYWORD_frozen },
{ "if", KEYWORD_if },
{ "implies", KEYWORD_implies },
{ "indexing", KEYWORD_indexing },
{ "infix", KEYWORD_infix },
{ "inherit", KEYWORD_inherit },
{ "inspect", KEYWORD_inspect },
{ "invariant", KEYWORD_invariant },
{ "is", KEYWORD_is },
{ "like", KEYWORD_like },
{ "local", KEYWORD_local },
{ "loop", KEYWORD_loop },
{ "not", KEYWORD_not },
{ "obsolete", KEYWORD_obsolete },
{ "old", KEYWORD_old },
{ "once", KEYWORD_once },
{ "or", KEYWORD_or },
{ "prefix", KEYWORD_prefix },
{ "redefine", KEYWORD_redefine },
{ "rename", KEYWORD_rename },
{ "require", KEYWORD_require },
{ "rescue", KEYWORD_rescue },
{ "result", KEYWORD_Result },
{ "retry", KEYWORD_retry },
{ "select", KEYWORD_select },
{ "separate", KEYWORD_separate },
{ "strip", KEYWORD_strip },
{ "then", KEYWORD_then },
{ "true", KEYWORD_true },
{ "undefine", KEYWORD_undefine },
{ "unique", KEYWORD_unique },
{ "until", KEYWORD_until },
{ "variant", KEYWORD_variant },
{ "when", KEYWORD_when },
{ "xor", KEYWORD_xor }
};
/*============================================================================
= Function prototypes
============================================================================*/
static void buildEiffelKeywordHash __ARGS((void));
static const char *tagName __ARGS((const tagType type));
static int tagLetter __ARGS((const tagType type));
static boolean includeTag __ARGS((const tagType type, const boolean fileScope));
static void qualifyClassTag __ARGS((tokenInfo *const token));
static void qualifyFeatureTag __ARGS((tokenInfo *const token));
static void qualifyLocalTag __ARGS((tokenInfo *const token));
static int skipToCharacter __ARGS((const int c));
static vString *parseInteger __ARGS((int c));
static vString *parseNumeric __ARGS((int c));
static int parseEscapedCharacter __ARGS((void));
static int parseCharacter __ARGS((void));
static void parseString __ARGS((vString *const string));
static void parseIdentifier __ARGS((vString *const string, const int firstChar));
static void parseFreeOperator __ARGS((vString *const string, const int firstChar));
static keywordId analyzeToken __ARGS((vString *const name));
static void readToken __ARGS((tokenInfo *const token));
static boolean isIdentifierMatch __ARGS((const tokenInfo *const token, const char *const name));
static void locateToken __ARGS((tokenInfo *const token, const tokenType type));
static void skipPastMatchingBracket __ARGS((tokenInfo *const token));
static void skipEntityType __ARGS((tokenInfo *const token));
static void parseLocal __ARGS((tokenInfo *const token));
static void findFeatureEnd __ARGS((tokenInfo *const token));
static boolean readFeatureName __ARGS((tokenInfo *const token));
static void parseFeature __ARGS((tokenInfo *const token));
static void parseExport __ARGS((tokenInfo *const token));
static void locateKeyword __ARGS((tokenInfo *const token, const keywordId keyword));
static void parseFeatureClauses __ARGS((tokenInfo *const token));
static void parseRename __ARGS((tokenInfo *const token));
static void parseInherit __ARGS((tokenInfo *const token));
static void parseClass __ARGS((tokenInfo *const token));
static tokenInfo *newToken __ARGS((void));
static void deleteToken __ARGS((tokenInfo *const token));
static void init __ARGS((void));
/*============================================================================
= Function definitions
============================================================================*/
static void buildEiffelKeywordHash()
{
const